package com.ilincar.utils;

import android.content.Context;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import java.util.HashMap;

import org.json.JSONObject;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Response;

/**
 * Created by ilincar on 2017/1/12.
 * 所有网络请求为post
 */

public class IlincarRequest {

    private final String TAG = "IlincarRequest";
    private Context mContext = null;
    private String mMacAddress = null;

    private final int TIME_OUT = 20;
    private int mCurrentTimeCnt = 0;
    private final int MAX_TIME_OUT_CNT = 3;
//    private HttpClient mHttpClient = null;

    public IlincarRequest(Context context) {
        this.mContext = context;
        mMacAddress = IlincarUtils.getIntMacByShell();
    }

    public interface RequestCallBack {
        void onFailure(Exception e);

        void onResponse(String result);
    }

    public interface DownloadCallBack {
        void onError(String message);

        void onSuccess(File file);

        void onLoading(long total, long current);
    }

    /**
     * 简单请求，不带参数
     *
     * @param url
     * @param callback
     */
    public void postToServer(final String url, final RequestCallBack callback) {
        OkHttpClient client = SingleHttpClient.getInstance().getHttpClient();
        client.newCall(SingleHttpClient.getInstance().newRequest(url, null, mMacAddress)).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                if (callback != null) {
                    callback.onFailure(e);
                }
            }

            @Override
            public void onResponse(Call call, Response resp) throws IOException {
                if (resp.isSuccessful()) {
                    try {
                        String result = IlincarUtils.getEncodeAndGzip(resp.body().string());
                        if (callback != null) {
                            callback.onResponse(result);
                        }
                    }
                    catch (Exception e) {
                        if (callback != null) {
                            callback.onFailure(e);
                        }
                    }
                }
                else {
                    if (callback != null) {
                        callback.onFailure(new Exception("access failed."));
                    }
                }
            }
        });
    }


    /**
     * 请求jsonObject ，参数放在 jsonObject 中
     *
     * @param url
     * @param jsonObject
     * @param callback
     */
    public void postToServer(final String url, final JSONObject jsonObject, final RequestCallBack callback) {

        try {
            OkHttpClient client = SingleHttpClient.getInstance().getHttpClient();
            String params = IlincarUtils.setEncodeAndGzip(jsonObject.toString());
            client.newCall(SingleHttpClient.getInstance().newRequest(url, params, mMacAddress)).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    if (callback != null) {
                        callback.onFailure(e);
                    }
                }

                @Override
                public void onResponse(Call call, Response resp) throws IOException {
                    if (resp.isSuccessful()) {
                        try {
                            String result = IlincarUtils.getEncodeAndGzip(resp.body().string());
                            if (callback != null) {
                                callback.onResponse(result);
                            }
                        }
                        catch (Exception e) {
                            if (callback != null) {
                                callback.onFailure(e);
                            }
                        }
                    }
                    else {
                        if (callback != null) {
                            callback.onFailure(new Exception("access failed."));
                        }
                    }
                }
            });
        } catch (Exception e) {
            if (callback != null) {
                callback.onFailure(e);
            }
        }
    }

    /**
     * 上传文件，请求，也包含json,可以都放在Map中
     *
     * @param url
     * @param bodyParams
     * @param callback
     */
    public void uploadFile(final String url, final HashMap<String, Object> bodyParams, final RequestCallBack callback) {

        try {
            OkHttpClient client = SingleHttpClient.getInstance().getHttpClient();
            client.newCall(SingleHttpClient.getInstance().newUploadRequest(url, bodyParams, mMacAddress)).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    if (callback != null) {
                        callback.onFailure(e);
                    }
                }

                @Override
                public void onResponse(Call call, Response resp) throws IOException {
                    if (resp.isSuccessful()) {
                        try {
                            String result = IlincarUtils.getEncodeAndGzip(resp.body().string());
                            if (callback != null) {
                                callback.onResponse(result);
                            }
                        }
                        catch (Exception e) {
                            if (callback != null) {
                                callback.onFailure(e);
                            }
                        }
                    }
                    else {
                        if (callback != null) {
                            callback.onFailure(new Exception("access failed."));
                        }
                    }
                }
            });
        } catch (Exception e) {
            if (callback != null) {
                callback.onFailure(e);
            }
        }

    }

    /**
     * 下载文件
     *
     * @param url          请求地址
     * @param saveFilePath 保存路径
     * @param fileName     保存的文件名
     * @param callback     回调接口
     */
    public void download(final String url, final String saveFilePath, final String fileName, final DownloadCallBack callback) {

        OkHttpClient client = SingleHttpClient.getInstance().getHttpClient();
        client.newCall(SingleHttpClient.getInstance().newRequest(url, mMacAddress)).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                if (callback != null) {
                    callback.onError("Download error.");
                }
            }

            @Override
            public void onResponse(Call call, Response resp) throws IOException {
                if (resp.isSuccessful()) {
                    final InputStream in = resp.body().byteStream();
                    FileOutputStream fileOutputStream = null;
                    try {

                        long lenth = resp.body().contentLength();
                        File filedir = new File(saveFilePath);
                        if (filedir.exists() && !filedir.mkdir() || !filedir.isDirectory()) {
                            if (callback != null) {
                                callback.onError("file path is error!");
                                return;
                            }
                        }

                        File file = new File(filedir, fileName);

                        fileOutputStream = new FileOutputStream(file);
                        int len = -1;
                        byte[] buf = new byte[1024];
                        int cc = 0;
                        while ((len = in.read(buf)) != -1) {
                            fileOutputStream.write(buf, 0, len);
                            cc ++;
                            if (callback != null && cc % 3 == 0) {
                                // 回调当前下载进度
                                cc = 0;
                                callback.onLoading(lenth, len);
                            }
                        }
                        buf = null;
                        callback.onLoading(lenth, lenth);
                        callback.onSuccess(file);
                        fileOutputStream.flush();
                    } catch (Exception e) {
                        if (callback != null) {
                            callback.onError("download error ! ");
                        }
                    } finally {
                        if (fileOutputStream != null) {
                            try {
                                fileOutputStream.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                        if (in != null) {
                            try {
                                in.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
                else {
                    if (callback != null) {
                        callback.onError("download error ! ");
                    }
                }
            }
        });
    }
}
